From 4037eca6aec47f21dcc3a990e83d70cb9cd92f5e Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 12 Aug 2004 15:55:07 +0000 Subject: [PATCH] bitkeeper revision 1.1159.25.1 (411b92dbFatpuCFS9px_DggrIbxQsg) Extra barriers in async shared-memory comms code. --- .../arch/xen/drivers/blkif/frontend/main.c | 12 +++--- .../arch/xen/kernel/ctrl_if.c | 42 ++++++++++++------- .../drivers/xen/blkback/blkback.c | 10 +++-- .../drivers/xen/blkfront/blkfront.c | 35 +++++++++------- .../drivers/xen/netback/netback.c | 1 + .../drivers/xen/netfront/netfront.c | 21 +++++----- tools/python/xen/lowlevel/xu/xu.c | 15 +++++++ 7 files changed, 88 insertions(+), 48 deletions(-) diff --git a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c index 63e8b1b5b2..b58976d452 100644 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c @@ -16,8 +16,6 @@ #include #include - - typedef unsigned char byte; /* from linux/ide.h */ #define BLKIF_STATE_CLOSED 0 @@ -95,6 +93,7 @@ static inline void translate_req_to_mfn(blkif_request_t *xreq, static inline void flush_requests(void) { DISABLE_SCATTERGATHER(); + wmb(); /* Ensure that the frontend can see the requests. */ blk_ring->req_prod = req_prod; notify_via_evtchn(blkif_evtchn); } @@ -533,7 +532,7 @@ static void kick_pending_request_queues(void) static void blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) { - BLKIF_RING_IDX i; + BLKIF_RING_IDX i, rp; unsigned long flags; struct buffer_head *bh, *next_bh; @@ -541,13 +540,14 @@ static void blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) if ( unlikely(blkif_state == BLKIF_STATE_CLOSED || recovery) ) { - printk("Bailed out\n"); - spin_unlock_irqrestore(&io_request_lock, flags); return; } - for ( i = resp_cons; i != blk_ring->resp_prod; i++ ) + rp = blk_ring->resp_prod; + rmb(); /* Ensure we see queued responses up to 'rp'. */ + + for ( i = resp_cons; i != rp; i++ ) { blkif_response_t *bret = &blk_ring->ring[MASK_BLKIF_IDX(i)].resp; switch ( bret->operation ) diff --git a/linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c b/linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c index c4ace2b6f9..3fc8d85ab1 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c @@ -93,8 +93,12 @@ static void __ctrl_if_tx_tasklet(unsigned long data) control_if_t *ctrl_if = get_ctrl_if(); ctrl_msg_t *msg; int was_full = TX_FULL(ctrl_if); + CONTROL_RING_IDX rp; - while ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod ) + rp = ctrl_if->tx_resp_prod; + rmb(); /* Ensure we see all requests up to 'rp'. */ + + while ( ctrl_if_tx_resp_cons != rp ) { msg = &ctrl_if->tx_ring[MASK_CONTROL_IDX(ctrl_if_tx_resp_cons)]; @@ -132,8 +136,12 @@ static void __ctrl_if_tx_tasklet(unsigned long data) static void __ctrl_if_rxmsg_deferred(void *unused) { ctrl_msg_t *msg; + CONTROL_RING_IDX dp; + + dp = ctrl_if_rxmsg_deferred_prod; + rmb(); /* Ensure we see all deferred requests up to 'dp'. */ - while ( ctrl_if_rxmsg_deferred_cons != ctrl_if_rxmsg_deferred_prod ) + while ( ctrl_if_rxmsg_deferred_cons != dp ) { msg = &ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX( ctrl_if_rxmsg_deferred_cons++)]; @@ -145,8 +153,13 @@ static void __ctrl_if_rx_tasklet(unsigned long data) { control_if_t *ctrl_if = get_ctrl_if(); ctrl_msg_t msg, *pmsg; + CONTROL_RING_IDX rp, dp; - while ( ctrl_if_rx_req_cons != ctrl_if->rx_req_prod ) + dp = ctrl_if_rxmsg_deferred_prod; + rp = ctrl_if->rx_req_prod; + rmb(); /* Ensure we see all requests up to 'rp'. */ + + while ( ctrl_if_rx_req_cons != rp ) { pmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if_rx_req_cons++)]; memcpy(&msg, pmsg, offsetof(ctrl_msg_t, msg)); @@ -161,20 +174,21 @@ static void __ctrl_if_rx_tasklet(unsigned long data) if ( test_bit(msg.type, (unsigned long *)&ctrl_if_rxmsg_blocking_context) ) - { - pmsg = &ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX( - ctrl_if_rxmsg_deferred_prod++)]; - memcpy(pmsg, &msg, offsetof(ctrl_msg_t, msg) + msg.length); + memcpy(&ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX(dp++)], + &msg, offsetof(ctrl_msg_t, msg) + msg.length); + else + (*ctrl_if_rxmsg_handler[msg.type])(&msg, 0); + } + + if ( dp != ctrl_if_rxmsg_deferred_prod ) + { + wmb(); + ctrl_if_rxmsg_deferred_prod = dp; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - schedule_task(&ctrl_if_rxmsg_deferred_tq); + schedule_task(&ctrl_if_rxmsg_deferred_tq); #else - schedule_work(&ctrl_if_rxmsg_deferred_work); + schedule_work(&ctrl_if_rxmsg_deferred_work); #endif - } - else - { - (*ctrl_if_rxmsg_handler[msg.type])(&msg, 0); - } } } diff --git a/linux-2.6.7-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6.7-xen-sparse/drivers/xen/blkback/blkback.c index d3e6b7456b..f26387f305 100644 --- a/linux-2.6.7-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6.7-xen-sparse/drivers/xen/blkback/blkback.c @@ -268,13 +268,15 @@ static int do_block_io_op(blkif_t *blkif, int max_to_do) { blkif_ring_t *blk_ring = blkif->blk_ring_base; blkif_request_t *req; - BLKIF_RING_IDX i; + BLKIF_RING_IDX i, rp; int more_to_do = 0; + rp = blk_ring->req_prod; + rmb(); /* Ensure we see queued requests up to 'rp'. */ + /* Take items off the comms ring, taking care not to overflow. */ for ( i = blkif->blk_req_cons; - (i != blk_ring->req_prod) && ((i-blkif->blk_resp_prod) != - BLKIF_RING_SIZE); + (i != rp) && ((i-blkif->blk_resp_prod) != BLKIF_RING_SIZE); i++ ) { if ( (max_to_do-- == 0) || (NR_PENDING_REQS == MAX_PENDING_REQS) ) @@ -533,7 +535,7 @@ static void make_response(blkif_t *blkif, unsigned long id, resp->id = id; resp->operation = op; resp->status = st; - wmb(); + wmb(); /* Ensure other side can see the response fields. */ blkif->blk_ring_base->resp_prod = ++blkif->blk_resp_prod; spin_unlock_irqrestore(&blkif->blk_ring_lock, flags); diff --git a/linux-2.6.7-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6.7-xen-sparse/drivers/xen/blkfront/blkfront.c index bd0ed84e56..331195f851 100644 --- a/linux-2.6.7-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6.7-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -82,6 +82,7 @@ static inline void translate_req_to_mfn(blkif_request_t *xreq, static inline void flush_requests(void) { + wmb(); /* Ensure that the frontend can see the requests. */ blk_ring->req_prod = req_prod; notify_via_evtchn(blkif_evtchn); } @@ -363,34 +364,39 @@ static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) { struct request *req; blkif_response_t *bret; - BLKIF_RING_IDX i; + BLKIF_RING_IDX i, rp; unsigned long flags; spin_lock_irqsave(&blkif_io_lock, flags); - if (unlikely(blkif_state == BLKIF_STATE_CLOSED || recovery)) { - printk("Bailed out\n"); - + if ( unlikely(blkif_state == BLKIF_STATE_CLOSED) || + unlikely(recovery) ) + { spin_unlock_irqrestore(&blkif_io_lock, flags); return IRQ_HANDLED; } - for (i = resp_cons; i != blk_ring->resp_prod; i++) { + rp = blk_ring->resp_prod; + rmb(); /* Ensure we see queued responses up to 'rp'. */ + + for ( i = resp_cons; i != rp; i++ ) + { bret = &blk_ring->ring[MASK_BLKIF_IDX(i)].resp; - switch (bret->operation) { + switch ( bret->operation ) + { case BLKIF_OP_READ: case BLKIF_OP_WRITE: - if (unlikely(bret->status != BLKIF_RSP_OKAY)) + if ( unlikely(bret->status != BLKIF_RSP_OKAY) ) DPRINTK("Bad return from blkdev data request: %lx\n", bret->status); req = (struct request *)bret->id; - /* XXXcl pass up status */ - if (unlikely(end_that_request_first(req, 1, - req->hard_nr_sectors))) + if ( unlikely(end_that_request_first + (req, + (bret->status != BLKIF_RSP_OKAY), + req->hard_nr_sectors)) ) BUG(); - end_that_request_last(req); - blkif_completion( bret, req ); + blkif_completion(bret, req); break; case BLKIF_OP_PROBE: memcpy(&blkif_control_rsp, bret, sizeof(*bret)); @@ -404,8 +410,9 @@ static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) resp_cons = i; resp_cons_rec = i; - if (xlbd_blk_queue && - test_bit(QUEUE_FLAG_STOPPED, &xlbd_blk_queue->queue_flags)) { + if ( (xlbd_blk_queue != NULL) && + test_bit(QUEUE_FLAG_STOPPED, &xlbd_blk_queue->queue_flags) ) + { blk_start_queue(xlbd_blk_queue); /* XXXcl call to request_fn should not be needed but * we get stuck without... needs investigating diff --git a/linux-2.6.7-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6.7-xen-sparse/drivers/xen/netback/netback.c index 6f92462529..8e3fbb75f9 100644 --- a/linux-2.6.7-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6.7-xen-sparse/drivers/xen/netback/netback.c @@ -446,6 +446,7 @@ static void net_tx_action(unsigned long unused) netif_put(netif); continue; } + rmb(); /* Ensure that we see the request. */ memcpy(&txreq, &netif->tx->ring[MASK_NETIF_TX_IDX(i)].req, sizeof(txreq)); netif->tx_req_cons++; diff --git a/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c index a9b59505bc..f33c292429 100644 --- a/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c @@ -118,10 +118,8 @@ static void netctrl_init(void) */ static int netctrl_err(int err) { - if(err < 0 && !netctrl.err){ + if ( (err < 0) && !netctrl.err ) netctrl.err = err; - printk(KERN_WARNING "%s> err=%d\n", __FUNCTION__, err); - } return netctrl.err; } @@ -177,7 +175,6 @@ static int network_open(struct net_device *dev) return 0; } - static void network_tx_buf_gc(struct net_device *dev) { NETIF_RING_IDX i, prod; @@ -190,6 +187,7 @@ static void network_tx_buf_gc(struct net_device *dev) do { prod = np->tx->resp_prod; + rmb(); /* Ensure we see responses up to 'rp'. */ for ( i = np->tx_resp_cons; i != prod; i++ ) { @@ -295,6 +293,7 @@ static void network_alloc_rx_buffers(struct net_device *dev) if ( rx_mcl[nr_pfns].args[5] != nr_pfns ) panic("Unable to reduce memory reservation\n"); + /* Above is a suitable barrier to ensure backend will see requests. */ np->rx->req_prod = i; } @@ -344,7 +343,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) tx->addr = virt_to_machine(skb->data); tx->size = skb->len; - wmb(); + wmb(); /* Ensure that backend will see the request. */ np->tx->req_prod = i + 1; network_tx_buf_gc(dev); @@ -392,7 +391,7 @@ static int netif_poll(struct net_device *dev, int *pbudget) struct net_private *np = dev->priv; struct sk_buff *skb; netif_rx_response_t *rx; - NETIF_RING_IDX i; + NETIF_RING_IDX i, rp; mmu_update_t *mmu = rx_mmu; multicall_entry_t *mcl = rx_mcl; int work_done, budget, more_to_do = 1; @@ -412,8 +411,11 @@ static int netif_poll(struct net_device *dev, int *pbudget) if ( (budget = *pbudget) > dev->quota ) budget = dev->quota; + rp = np->rx->resp_prod; + rmb(); /* Ensure we see queued responses up to 'rp'. */ + for ( i = np->rx_resp_cons, work_done = 0; - (i != np->rx->resp_prod) && (work_done < budget); + (i != rp) && (work_done < budget); i++, work_done++ ) { rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp; @@ -904,9 +906,8 @@ void netif_suspend(void) void netif_resume(void) { - ctrl_msg_t cmsg; - netif_fe_interface_connect_t up; -// netif_fe_driver_status_changed_t st; + ctrl_msg_t cmsg; + netif_fe_interface_connect_t up; struct net_device *dev = NULL; struct net_private *np = NULL; int i; diff --git a/tools/python/xen/lowlevel/xu/xu.c b/tools/python/xen/lowlevel/xu/xu.c index 0a118b7f0f..2a4f229fef 100644 --- a/tools/python/xen/lowlevel/xu/xu.c +++ b/tools/python/xen/lowlevel/xu/xu.c @@ -49,6 +49,13 @@ /* Size of a machine page frame. */ #define PAGE_SIZE 4096 +#if defined(__i386__) +#define rmb() __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" ) +#define wmb() __asm__ __volatile__ ( "" : : : "memory" ) +#else +#error "Define barriers" +#endif + /* * *********************** NOTIFIER *********************** @@ -710,6 +717,9 @@ static PyObject *xu_port_read_request(PyObject *self, PyObject *args) return NULL; } + /* Need to ensure we see the request, despite seeing the index update.*/ + rmb(); + cmsg = &cif->tx_ring[MASK_CONTROL_IDX(c)]; xum = PyObject_New(xu_message_object, &xu_message_type); memcpy(&xum->msg, cmsg, sizeof(*cmsg)); @@ -745,6 +755,7 @@ static PyObject *xu_port_write_request(PyObject *self, PyObject *args) cmsg = &cif->rx_ring[MASK_CONTROL_IDX(p)]; memcpy(cmsg, &xum->msg, sizeof(*cmsg)); + wmb(); xup->rx_req_prod = cif->rx_req_prod = p + 1; Py_INCREF(Py_None); @@ -768,6 +779,9 @@ static PyObject *xu_port_read_response(PyObject *self, PyObject *args) return NULL; } + /* Need to ensure we see the response, despite seeing the index update.*/ + rmb(); + cmsg = &cif->rx_ring[MASK_CONTROL_IDX(c)]; xum = PyObject_New(xu_message_object, &xu_message_type); memcpy(&xum->msg, cmsg, sizeof(*cmsg)); @@ -803,6 +817,7 @@ static PyObject *xu_port_write_response(PyObject *self, PyObject *args) cmsg = &cif->tx_ring[MASK_CONTROL_IDX(p)]; memcpy(cmsg, &xum->msg, sizeof(*cmsg)); + wmb(); xup->tx_resp_prod = cif->tx_resp_prod = p + 1; Py_INCREF(Py_None); -- 2.30.2